/**
 * 
 */
package ch.unisi.inf.pfii.teamred.pacman.model;

import java.util.ArrayList;

/**
 * This class describes a level of the Pacman game.
 * 
 * @author mark.pruneri@lu.unisi.ch
 * @author luca.vignola@lu.unisi.ch
 */
public final class Level {

	private final int levelNumber;
	private final String levelName;

	private static final int[][] DEFAULT_LEVEL = {
			{ 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
					5, 5, 5, 5, 5, 2 },
			{ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 8 },
			{ 7, 0, 13, 10, 10, 14, 0, 13, 10, 10, 10, 14, 0, 16, 15, 0, 13,
					10, 10, 10, 14, 0, 13, 10, 10, 14, 0, 8 },
			{ 7, 19, 16, 17, 17, 15, 0, 16, 17, 17, 17, 15, 0, 16, 15, 0, 16,
					17, 17, 17, 15, 0, 16, 17, 17, 15, 19, 8 },
			{ 7, 0, 11, 9, 9, 12, 0, 11, 9, 9, 9, 12, 0, 11, 12, 0, 11, 9, 9,
					9, 12, 0, 11, 9, 9, 12, 0, 8 },
			{ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 8 },
			{ 7, 0, 13, 10, 10, 14, 0, 13, 14, 0, 13, 10, 10, 10, 10, 10, 10,
					14, 0, 13, 14, 0, 13, 10, 10, 14, 0, 8 },
			{ 7, 0, 11, 9, 9, 12, 0, 16, 15, 0, 11, 9, 9, 23, 22, 9, 9, 12, 0,
					16, 15, 0, 11, 9, 9, 12, 0, 8 },
			{ 7, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 16,
					15, 0, 0, 0, 0, 0, 0, 8 },
			{ 3, 6, 6, 6, 6, 26, 0, 16, 20, 10, 10, 14, 0, 16, 15, 0, 13, 10,
					10, 21, 15, 0, 27, 6, 6, 6, 6, 4 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 22, 9, 9, 12, 0, 11, 12, 0, 11, 9,
					9, 23, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 15, 18, 18, 18, 18, 18, 18, 18, 18,
					18, 18, 16, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 15, 18, 13, 10, 10, 18, 18, 10, 10,
					14, 18, 16, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 1, 5, 5, 5, 5, 25, 0, 11, 12, 18, 16, 18, 18, 18, 18, 18, 18, 15,
					18, 11, 12, 0, 24, 5, 5, 5, 5, 2 },
			{ 7, 0, 0, 0, 0, 0, 0, 18, 18, 18, 16, 18, 18, 18, 18, 18, 18, 15,
					18, 18, 18, 0, 0, 0, 0, 0, 0, 8 }, // tunnel
			{ 7, 0, 0, 0, 0, 0, 0, 18, 18, 18, 16, 18, 18, 18, 18, 18, 18, 15,
					18, 18, 18, 0, 0, 0, 0, 0, 0, 8 },
			{ 3, 6, 6, 6, 6, 26, 0, 13, 14, 18, 16, 18, 18, 18, 18, 18, 18, 15,
					18, 13, 14, 0, 27, 6, 6, 6, 6, 4 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 15, 18, 11, 9, 9, 9, 9, 9, 9, 12,
					18, 16, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 15, 18, 18, 18, 18, 18, 18, 18, 18,
					18, 18, 16, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 17, 17, 17, 17, 17, 7, 0, 16, 15, 0, 13, 10, 10, 10, 10, 10, 10,
					14, 0, 16, 15, 0, 8, 17, 17, 17, 17, 17 },
			{ 1, 5, 5, 5, 5, 25, 0, 11, 12, 0, 11, 9, 9, 23, 22, 9, 9, 12, 0,
					11, 12, 0, 24, 5, 5, 5, 5, 2 },
			{ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 8 },
			{ 7, 0, 13, 10, 10, 14, 0, 13, 10, 10, 10, 14, 0, 16, 15, 0, 13,
					10, 10, 10, 14, 0, 13, 10, 10, 14, 0, 8 },
			{ 7, 0, 11, 9, 23, 15, 0, 11, 9, 9, 9, 12, 0, 11, 12, 0, 11, 9, 9,
					9, 12, 0, 16, 22, 9, 12, 0, 8 },
			{ 7, 19, 0, 0, 16, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
					0, 16, 15, 0, 0, 19, 8 },
			{ 7, 10, 14, 0, 16, 15, 0, 13, 14, 0, 13, 10, 10, 10, 10, 10, 10,
					14, 0, 13, 14, 0, 16, 15, 0, 13, 10, 8 },
			{ 7, 9, 12, 0, 11, 12, 0, 16, 15, 0, 11, 9, 9, 23, 22, 9, 9, 12, 0,
					16, 15, 0, 11, 12, 0, 11, 9, 8 },
			{ 7, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 16,
					15, 0, 0, 0, 0, 0, 0, 8 },
			{ 7, 0, 13, 10, 10, 10, 10, 21, 20, 10, 10, 14, 0, 16, 15, 0, 13,
					10, 10, 21, 20, 10, 10, 10, 10, 14, 0, 8 },
			{ 7, 0, 11, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 11, 12, 0, 11, 9, 9, 9,
					9, 9, 9, 9, 9, 12, 0, 8 },
			{ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 8 },
			{ 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
					6, 6, 6, 6, 6, 4 } };

	private Board board;

	public Level(final int levelNumber, final String levelName) {
		this.levelName = levelName;
		this.levelNumber = levelNumber;

		createLevel();
	}

	public final int getLevelNumber() {
		return levelNumber;
	}

	public final String getLevelName() {
		return levelName;
	}

	public final Board getBoard() {
		return board;
	}

	public final void restart() {
		board.restart();
	}

	public final String getStatus() {
		return "Level: " + levelName + "  #: " + levelNumber;
	}

	private final void createLevel() {
		int cols = DEFAULT_LEVEL[0].length;
		int rows = DEFAULT_LEVEL.length;
		Block[][] blocks = new Block[cols][rows];

		for (int r = 0; r < rows; r++) {
			for (int c = 0; c < cols; c++) {
				switch (DEFAULT_LEVEL[r][c]) {
				case 0:
					blocks[c][r] = new Floor(new Pill());
					break;
				case 1:
					blocks[c][r] = new Wall(1);
					break;
				case 2:
					blocks[c][r] = new Wall(2);
					break;
				case 3:
					blocks[c][r] = new Wall(3);
					break;
				case 4:
					blocks[c][r] = new Wall(4);
					break;
				case 5:
					blocks[c][r] = new Wall(5);
					break;
				case 6:
					blocks[c][r] = new Wall(6);
					break;
				case 7:
					blocks[c][r] = new Wall(7);
					break;
				case 8:
					blocks[c][r] = new Wall(8);
					break;
				case 9:
					blocks[c][r] = new Wall(9);
					break;
				case 10:
					blocks[c][r] = new Wall(10);
					break;
				case 11:
					blocks[c][r] = new Wall(11);
					break;
				case 12:
					blocks[c][r] = new Wall(12);
					break;
				case 13:
					blocks[c][r] = new Wall(13);
					break;
				case 14:
					blocks[c][r] = new Wall(14);
					break;
				case 15:
					blocks[c][r] = new Wall(15);
					break;
				case 16:
					blocks[c][r] = new Wall(16);
					break;
				case 17:
					blocks[c][r] = new Wall(17);
					break;
				case 18:
					blocks[c][r] = new Floor();
					break;
				case 19:
					blocks[c][r] = new Floor(new PowerPill());
					break;
				case 20:
					blocks[c][r] = new Wall(20);
					break;
				case 21:
					blocks[c][r] = new Wall(21);
					break;
				case 22:
					blocks[c][r] = new Wall(22);
					break;
				case 23:
					blocks[c][r] = new Wall(23);
					break;
				case 24:
					blocks[c][r] = new Wall(24);
					break;
				case 25:
					blocks[c][r] = new Wall(25);
					break;
				case 26:
					blocks[c][r] = new Wall(26);
					break;
				case 27:
					blocks[c][r] = new Wall(27);
					break;
				default:
					blocks[c][r] = new Wall(17);
				}
			}
		}

		ArrayList<Creature> creatures = new ArrayList<Creature>();
		
		Position startPacman = new Position(5, 13);
		Position startGhost1 = new Position(11, 15);
		Position startGhost2 = new Position(13, 13);
		Position startGhost3 = new Position(13, 14);
		Position startGhost4 = new Position(11, 12);
		
		Pacman pacman = new Pacman(startPacman, Direction.STOP);
		Ghost ghost1 = new Blinky(startGhost1, Direction.UP);
		Ghost ghost2 = new Clyde(startGhost2, Direction.UP);
		Ghost ghost3 = new Inky(startGhost3, Direction.UP);
		Ghost ghost4 = new Pinky(startGhost4, Direction.UP);
		
		creatures.add(pacman);
		creatures.add(ghost1);
		creatures.add(ghost2);
		creatures.add(ghost3);
		creatures.add(ghost4);

		board = new Board(blocks, creatures);
	}
}
